package com.example.vpn_demo

import android.content.Intent
import android.content.pm.ApplicationInfo
import android.content.pm.PackageManager
import android.net.VpnService
import android.os.Bundle
import android.util.Log
import android.widget.Toast
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.activity.result.contract.ActivityResultContracts
import androidx.compose.foundation.layout.*
import androidx.compose.material3.*
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.unit.dp
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import androidx.core.content.FileProvider
import java.io.File
import android.app.AlertDialog
import androidx.compose.foundation.text.selection.SelectionContainer
import com.example.vpn_demo.cert.CertificateManager
import android.os.Build
import android.provider.Settings
import android.os.Environment
import android.Manifest

data class AppInfo(
    val packageName: String,
    val appName: String,
    var isSelected: Boolean = false
)

class MainActivity : ComponentActivity() {
    companion object {
        private const val TAG = "MainActivity"
        private const val REQUEST_STORAGE_PERMISSION = 1001
    }

    private val certificateManager by lazy { CertificateManager(this) }

    private var vpnStarted by mutableStateOf(false)
    private var selectedApps = listOf<String>()
    
    private var appListState = mutableStateOf<List<AppInfo>>(emptyList())
    
    private val vpnLauncher = registerForActivityResult(
        ActivityResultContracts.StartActivityForResult()
    ) { result ->
        if (result.resultCode == RESULT_OK) {
            startVpnService(selectedApps)
            vpnStarted = true
        }
    }

    private val permissionLauncher = registerForActivityResult(
        ActivityResultContracts.RequestPermission()
    ) { isGranted ->
        if (isGranted) {
            appListState.value = getInstalledApps()
            showToast("已获取应用列表权限")
        } else {
            showToast("无法获取应用列表，请授予权限")
        }
    }

    private val storagePermissionLauncher = registerForActivityResult(
        ActivityResultContracts.RequestMultiplePermissions()
    ) { permissions ->
        if (permissions.all { it.value }) {
            showToast("已获取存储权限")
        } else {
            showToast("无法获取存储权限，证书导出可能失败")
        }
    }

    private fun getInstalledApps(): List<AppInfo> {
        val pm = packageManager
        return pm.getInstalledPackages(PackageManager.GET_META_DATA)
            .filter { packageInfo ->
                // 过滤掉系统应用和自己的应用
                !isSystemApp(packageInfo.applicationInfo) && 
                packageInfo.packageName != packageName &&
                // 确保应用有启动器图标（即用户可以打开的应用）
                pm.getLaunchIntentForPackage(packageInfo.packageName) != null
            }
            .mapNotNull { packageInfo ->
                try {
                    AppInfo(
                        packageName = packageInfo.packageName,
                        appName = pm.getApplicationLabel(packageInfo.applicationInfo).toString()
                    )
                } catch (e: Exception) {
                    null
                }
            }
            .sortedBy { it.appName }
    }

    private fun isSystemApp(appInfo: ApplicationInfo): Boolean {
        return appInfo.flags and (ApplicationInfo.FLAG_SYSTEM or ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0
    }

    private fun showToast(message: String) {
        Toast.makeText(this, message, Toast.LENGTH_SHORT).show()
    }

    private fun startVpnService(selectedApps: List<String>) {
        CoroutineScope(Dispatchers.IO).launch {
            try {
                val intent = Intent(this@MainActivity, MyVpnService::class.java).apply {
                    putStringArrayListExtra("selected_apps", ArrayList(selectedApps))
                }
                startService(intent)
                withContext(Dispatchers.Main) {
                    showToast("VPN 已启动，正在抓取 ${selectedApps.size} 个应用的网络请求")
                }
            } catch (e: Exception) {
                Log.e("MainActivity", "启动 VPN 服务失败", e)
                withContext(Dispatchers.Main) {
                    showToast("启动 VPN 服务失败：${e.message}")
                }
            }
        }
    }

    private fun checkAndRequestStoragePermissions() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
            // Android 11 及以上版本需要 MANAGE_EXTERNAL_STORAGE 权限
            if (!Environment.isExternalStorageManager()) {
                try {
                    val intent = Intent(Settings.ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION)
                    startActivity(intent)
                    Toast.makeText(this, "请授予所有文件访问权限", Toast.LENGTH_LONG).show()
                } catch (e: Exception) {
                    Log.e(TAG, "请求存储权限失败", e)
                    Toast.makeText(this, "请求权限失败: ${e.message}", Toast.LENGTH_SHORT).show()
                }
                return
            }
        } else {
            // Android 10 及以下版本使用传统存储权限
            val permissions = mutableListOf(
                Manifest.permission.READ_EXTERNAL_STORAGE
            )
            
            if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.Q) {
                permissions.add(Manifest.permission.WRITE_EXTERNAL_STORAGE)
            }
            
            // 检查是否已经有权限
            val hasPermissions = permissions.all {
                checkSelfPermission(it) == PackageManager.PERMISSION_GRANTED
            }
            
            if (!hasPermissions) {
                storagePermissionLauncher.launch(permissions.toTypedArray())
                return
            }
        }
    }

    private fun requestStoragePermissions() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
            // Android 11 及以上使用 MANAGE_EXTERNAL_STORAGE 权限
            if (!Environment.isExternalStorageManager()) {
                try {
                    val intent = Intent(Settings.ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION)
                    startActivity(intent)
                } catch (e: Exception) {
                    Log.e("MainActivity", "请求存储权限失败", e)
                }
            }
        } else {
            // Android 10 及以下使用传统存储权限
            if (checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) 
                != PackageManager.PERMISSION_GRANTED) {
                requestPermissions(
                    arrayOf(
                        Manifest.permission.WRITE_EXTERNAL_STORAGE,
                        Manifest.permission.READ_EXTERNAL_STORAGE
                    ),
                    REQUEST_STORAGE_PERMISSION
                )
            }
        }
    }

    @Composable
    private fun CertificateDialog(
        onDismiss: () -> Unit = {}
    ) {
        val context = LocalContext.current
        val certificateManager = remember { CertificateManager(context) }
        var showHelpDialog by remember { mutableStateOf(false) }
        
        // 检查证书是否已安装
        LaunchedEffect(Unit) {
            if (certificateManager.checkCertificateInstallation()) {
                Log.i(TAG, "CA 证书已安装")
                Toast.makeText(context, "CA 证书已正确安装", Toast.LENGTH_SHORT).show()
                onDismiss()  // 如果证书已安装，关闭对话框
                return@LaunchedEffect
            }
            Log.w(TAG, "CA 证书未安装")
        }

        if (showHelpDialog) {
            AlertDialog(
                onDismissRequest = { showHelpDialog = false },
                title = { Text("安装说明") },
                text = {
                    Column {
                        Text("方法一：使用证书安装器")
                        Text("1. 确保设备已设置锁屏密码")
                        Text("2. 点击【安装证书】按钮")
                        Text("3. 选择【CA 证书】")
                        Text("4. 按照系统提示完成安装")
                        Spacer(modifier = Modifier.height(16.dp))
                        Text("方法二：通过系统设置安装")
                        Text("1. 证书已导出到：")
                        Text("   下载目录/vpn_demo_ca.crt")
                        Text("2. 打开系统设置")
                        Text("3. 安全 -> 加密与凭据 -> 从存储设备安装")
                        Text("4. 选择【CA 证书】")
                        Text("5. 找到并选择 vpn_demo_ca.crt")
                    }
                },
                confirmButton = {
                    Row {
                        TextButton(
                            onClick = {
                                try {
                                    // 检查权限
                                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R && !Environment.isExternalStorageManager()) {
                                        checkAndRequestStoragePermissions()
                                        return@TextButton
                                    }
                                    
                                    val certFile = certificateManager.exportCertificate()
                                    // 使用证书安装器
                                    val uri = FileProvider.getUriForFile(
                                        context,
                                        "${context.packageName}.provider",
                                        certFile
                                    )
                                    val intent = Intent(Intent.ACTION_VIEW).apply {
                                        setDataAndType(uri, "application/x-x509-ca-cert")
                                        addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
                                        addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
                                    }
                                    context.startActivity(intent)
                                    
                                    Toast.makeText(
                                        context,
                                        "证书已导出到下载目录: vpn_demo_ca.crt",
                                        Toast.LENGTH_LONG
                                    ).show()
                                } catch (e: Exception) {
                                    Log.e(TAG, "导出证书失败", e)
                                    Toast.makeText(
                                        context, 
                                        "导出证书失败: ${e.message}", 
                                        Toast.LENGTH_LONG
                                    ).show()
                                }
                            }
                        ) {
                            Text("安装证书")
                        }
                        TextButton(
                            onClick = {
                                try {
                                    certificateManager.exportCertificate()
                                    val intent = Intent(android.provider.Settings.ACTION_SECURITY_SETTINGS)
                                    context.startActivity(intent)
                                } catch (e: Exception) {
                                    Log.e(TAG, "导出证书失败", e)
                                    Toast.makeText(context, "导出证书失败: ${e.message}", Toast.LENGTH_SHORT).show()
                                }
                            }
                        ) {
                            Text("打开系统设置")
                        }
                        TextButton(onClick = { showHelpDialog = false }) {
                            Text("关闭")
                        }
                    }
                }
            )
        }

        AlertDialog(
            onDismissRequest = onDismiss,
            title = { Text("CA 证书未安装") },
            text = { Text("需要安装 CA 证书才能抓取 HTTPS 请求。请选择安装方式。") },
            confirmButton = {
                TextButton(onClick = { showHelpDialog = true }) {
                    Text("查看安装说明")
                }
            },
            dismissButton = {
                TextButton(onClick = onDismiss) {
                    Text("取消")
                }
            }
        )
    }

    @OptIn(ExperimentalMaterial3Api::class)
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        
        requestPermissionAndLoadApps()
        
        setContent {
            var vpnEnabled by remember { mutableStateOf(vpnStarted) }
            var showAppSelector by remember { mutableStateOf(false) }
            var apps by remember { appListState }
            var showCertDialog by remember { mutableStateOf(false) }
            
            if (showCertDialog) {
                CertificateDialog(
                    onDismiss = {
                        showCertDialog = false
                    }
                )
            }
            
            Scaffold { padding ->
                Column(
                    modifier = Modifier
                        .fillMaxSize()
                        .padding(padding)
                        .padding(16.dp),
                    horizontalAlignment = Alignment.CenterHorizontally,
                    verticalArrangement = Arrangement.spacedBy(16.dp)
                ) {
                    Button(
                        onClick = { requestPermissionAndLoadApps() },
                        modifier = Modifier.fillMaxWidth()
                    ) {
                        Text("刷新应用列表")
                    }

                    if (apps.isEmpty()) {
                        Text("没有找到可用的应用", modifier = Modifier.padding(16.dp))
                    } else {
                        ExposedDropdownMenuBox(
                            expanded = showAppSelector,
                            onExpandedChange = { showAppSelector = !showAppSelector },
                            modifier = Modifier.fillMaxWidth()
                        ) {
                            TextField(
                                value = "${apps.count { it.isSelected }} 个应用被选中",
                                onValueChange = {},
                                readOnly = true,
                                trailingIcon = { ExposedDropdownMenuDefaults.TrailingIcon(expanded = showAppSelector) },
                                modifier = Modifier.menuAnchor()
                            )
                            
                            ExposedDropdownMenu(
                                expanded = showAppSelector,
                                onDismissRequest = { showAppSelector = false }
                            ) {
                                apps.forEach { app ->
                                    DropdownMenuItem(
                                        text = {
                                            Row(
                                                horizontalArrangement = Arrangement.SpaceBetween,
                                                modifier = Modifier.fillMaxWidth()
                                            ) {
                                                Text(app.appName)
                                                Checkbox(
                                                    checked = app.isSelected,
                                                    onCheckedChange = null
                                                )
                                            }
                                        },
                                        onClick = {
                                            apps = apps.map {
                                                if (it.packageName == app.packageName) {
                                                    it.copy(isSelected = !it.isSelected)
                                                } else {
                                                    it
                                                }
                                            }
                                        }
                                    )
                                }
                            }
                        }
                    }

                    Button(
                        onClick = {
                            if (!vpnEnabled) {
                                selectedApps = apps.filter { it.isSelected }
                                    .map { it.packageName }
                                
                                if (selectedApps.isEmpty()) {
                                    showToast("请至少选择一个应用")
                                    return@Button
                                }
                                
                                try {
                                    val vpnIntent = VpnService.prepare(this@MainActivity)
                                    if (vpnIntent != null) {
                                        vpnLauncher.launch(vpnIntent)
                                    } else {
                                        startVpnService(selectedApps)
                                        vpnEnabled = true
                                    }
                                } catch (e: Exception) {
                                    Log.e("MainActivity", "准备 VPN 失败", e)
                                    showToast("准备 VPN 失败：${e.message}")
                                }
                            } else {
                                try {
                                    stopService(Intent(this@MainActivity, MyVpnService::class.java))
                                    vpnEnabled = false
                                    showToast("VPN 已停止")
                                } catch (e: Exception) {
                                    Log.e("MainActivity", "停止 VPN 服务失败", e)
                                    showToast("停止 VPN 服务失败：${e.message}")
                                }
                            }
                        }
                    ) {
                        Text(if (vpnEnabled) "停止抓包" else "开始抓包")
                    }

                    Button(
                        onClick = { showCertDialog = true },
                        modifier = Modifier.fillMaxWidth()
                    ) {
                        Text("检查证书")
                    }
                }
            }
        }
    }

    private fun requestPermissionAndLoadApps() {
        if (checkSelfPermission(android.Manifest.permission.QUERY_ALL_PACKAGES) 
            == PackageManager.PERMISSION_GRANTED) {
            appListState.value = getInstalledApps()
        } else {
            permissionLauncher.launch(android.Manifest.permission.QUERY_ALL_PACKAGES)
        }
    }

    override fun onRequestPermissionsResult(
        requestCode: Int,
        permissions: Array<out String>,
        grantResults: IntArray
    ) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults)
        when (requestCode) {
            REQUEST_STORAGE_PERMISSION -> {
                if (grantResults.isNotEmpty() && 
                    grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    // 权限已授予，可以继续导出证书
                } else {
                    Toast.makeText(this, "需要存储权限才能导出证书", Toast.LENGTH_SHORT).show()
                }
            }
        }
    }

    private fun exportCertificate() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
            if (!Environment.isExternalStorageManager()) {
                requestStoragePermissions()
                return
            }
        } else if (checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) 
            != PackageManager.PERMISSION_GRANTED) {
            requestStoragePermissions()
            return
        }

        try {
            val certFile = certificateManager.exportCertificate()
            Toast.makeText(this, "证书已导出到: ${certFile.absolutePath}", Toast.LENGTH_LONG).show()
        } catch (e: Exception) {
            Toast.makeText(this, "导出证书失败: ${e.message}", Toast.LENGTH_SHORT).show()
        }
    }
}